// JointGenerator.cpp: implementation of the JointGenerator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "phsshare.h"
#include "JointGenerator.h"
#include "JointGeneratorArithmetic.h"
#include "SupportHanger.h"
#include "Project.h"
#include "JointRegularSet.h"
#include "PersistentFacade.h"
#include "KnownPartSet.h"
#include "Joint.h"
#include "JointFunction.h"
using namespace DAWrapper;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

namespace VersionControl
{
	JointGenerator::JointGenerateArithmeticGenerator JointGenerator::m_ArithmeticGenerator;
	
	JointGenerator::JointGenerateArithmeticRegister& JointGenerator::GetJointGenerateArithmetics()
	{
		return *(m_ArithmeticGenerator.Generate());
	}
	
	JointGenerator::JointGenerator(Part* pFirst, Part* pNext):m_First(pFirst), m_Next(pNext)
	{
		m_pFirst = pFirst;
		m_pNext = pNext;
	}
	
	JointGenerator::JointGenerator():m_First(NULL),m_Next(NULL)
	{
		m_pFirst = NULL;
		m_pNext = NULL;
	}

	JointGenerator::~JointGenerator()
	{
		
	}
	
	BOOL JointGenerator::RunArithmetic(INT nArithmeticIndex, Joint*& pJoint)
	{	
		JointGeneratorArithmetic* pArithmetic = NULL;
		pArithmetic = GetJointGenerateArithmetics().Get(nArithmeticIndex)->CreateObject();
		if(pArithmetic != NULL)
		{
			pArithmetic->SetJoinPart(&m_First, &m_Next);
			if(pArithmetic->Execute(pJoint))
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}
		return FALSE;
	}

	Joint* JointGenerator::Generate(DAWrapper::RecordsetPtrWrap& rs)
	{
		INT nPrevPartID = 0;
		INT nNextPartID = 0;
		CString strPrevPortID;
		CString strNextPortID;

		nPrevPartID = rs.GetInt(_T("Part_ID_1"));
		nNextPartID = rs.GetInt(_T("Part_ID_2"));

		strPrevPortID = rs.GetString(_T("JP_ID_1"));
		strNextPortID = rs.GetString(_T("JP_ID_2"));

		Joint* pJoint = new Joint(nPrevPartID, strPrevPortID, nNextPartID, strNextPortID);
		if(pJoint == NULL)
		{
			ASSERT(pJoint);
			::ReportMemoryError();
			return NULL;
		}

		ASSERT(project());
		pJoint->project(project());
		SupportHanger* pSH = project()->GetSupportHangerManager().
			GetSupportHanger(rs.GetString(_T("SH_ID")));
		ASSERT(pSH);
		pJoint->SupportHangerOwner(pSH);
		pJoint->JointIndex(rs.GetInt(_T("Joint_ID")));
		pJoint->GetPointer();
		GetJointAttachs(pJoint, rs);
		pJoint->SetRead();
		return pJoint;
	}

	void JointGenerator::GetJointAttachs(Joint* pJoint, DAWrapper::RecordsetPtrWrap& jointrs)
	{
		ASSERT(pJoint);
		
		ASSERT(pJoint->SupportHangerOwner());
		CString strSql;
		strSql.Format(_T("Select * from Properties_Of_Part where Part_ID = %d and SH_ID = '%s'"),
			pJoint->JointIndex(), pJoint->SupportHangerOwner()->SupportHangerID());

		RecordsetPtrWrap rs;
		_ConnectionPtr pCon = jointrs.GetSource();
		ASSERT(pCon != NULL);

		HRESULT hr = rs.Set(strSql, pCon);
		if(hr != S_OK)
		{
			ASSERT(FALSE);
			return;
		}

		CString strPropertyID;
		while(!rs.IsBOF() && !rs.IsEOF())
		{
			strPropertyID = rs.GetString(_T("Property_ID"));
			ASSERT(strPropertyID);

			pJoint->SetVariableValue(strPropertyID, vtos(rs.GetCollect(_T("Property_Value"))));
			ASSERT(pJoint->GetProperty(strPropertyID));
			pJoint->GetProperty(strPropertyID)->SetKnown();
			rs.MoveNext();
		} 
	}
	
	Joint* JointGenerator::Create(JointFunction* pFirst, JointFunction* pNext)
	{
		JointRegularSet* pSet = GetPersistentFacade().GetJointRegularSet();
		if(!pSet->IsLegal(pFirst->GetJointStyle(), pNext->GetJointStyle()))
		{
			return NULL;
		}
		
		Joint* pJoint = NULL;
		pJoint = new Joint(pFirst, pNext);
		if(pJoint == NULL)
		{
			ReportMemoryError();
			return NULL;
		}
		
		ASSERT(project());
		pJoint->project(project());
		if(!pJoint->GetRegular())
		{
			delete pJoint;
			return NULL;
		}
		
		pFirst->SetJoint(pJoint);
		pNext->SetJoint(pJoint);
		
		return pJoint;
	}
	
}
